home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
HENSA
/
MISC
/
SHELL.ARC
/
Shell
/
Sources
/
c
/
GFX
< prev
next >
Wrap
Text File
|
1994-11-21
|
8KB
|
353 lines
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "DeskLib:GFX.h"
#include "DeskLib:Coord.h"
#include "DeskLib:WimpSWIs.h"
#include "DeskLib:Error.h"
#include "DeskLib:Window.h"
#include "DeskLib:Event.h"
#include "Shell.Extra.h"
#include "Shell.SafeAlloc.h"
#include "Shell.PlotIcon.h"
#include "Shell.Redraw2.h"
Shell_windblock Shell_windows[ Shell_MAXWINDS];
int Shell_numwinds = 0;
void Shell_WindRedraw2( wimp_rect *workrect, Shell_convertpoint convert, Shell_windblock *wind)
/* This takes a workarea rectangle and redraws */
/* any shell-rectangles in Shell window 'wind' */
/* which overlap with it. */
{
Shell_rectblock *rectblock;
for (
rectblock = LinkList_FirstItem( &wind->anchor);
rectblock;
rectblock = LinkList_NextItem( &rectblock->header)
)
{
if ( rectblock->plot_icon) {
/* The rect should be plotted as an icon - e.g. for a border, and a */
/* background colour. Also, we will set the grapics colour to the icon */
/* foreground colour here. */
if ( Coord_RectsOverlap( workrect, &rectblock->icon.workarearect))
Shell_PlotIcon( &rectblock->icon, convert);
/* Shell_PlotIcon is identical to Wimp_PlotIcon, but */
/* only sends 16 bit coors to Wimp_PlotIcon, so arbitarily */
/* sized icons can be plotted */
Wimp_SetColour( rectblock->icon.flags.data.foreground);
}
if ( Coord_RectsOverlap( workrect, &rectblock->rect)) {
/* Set things up so the redrawer only has to work in coors relative */
/* to this rectblock's origin. */
Shell_convertpoint localconvert;
wimp_rect localredrawrect;
wimp_point localsize;
localsize.x = rectblock->rect.max.x - rectblock->rect.min.x;
localsize.y = rectblock->rect.max.y - rectblock->rect.min.y;
localconvert.x = convert.x + rectblock->rect.min.x;
localconvert.y = convert.y + rectblock->rect.min.y;
localredrawrect.min.x = workrect->min.x - rectblock->rect.min.x;
localredrawrect.max.x = workrect->max.x - rectblock->rect.min.x;
localredrawrect.min.y = workrect->min.y - rectblock->rect.min.y;
localredrawrect.max.y = workrect->max.y - rectblock->rect.min.y;
(*rectblock->redrawer)
(
localconvert,
localsize,
rectblock->reference,
&localredrawrect
);
}
}
return;
}
static BOOL Shell_WindRedraw( event_pollblock *event, void *reference)
{ Shell_windblock *info = (Shell_windblock *) reference;
Shell_convertpoint convert;
wimp_rect workrect;
window_redrawblock redrawblock;
BOOL more;
redrawblock.window = event->data.openblock.window;
Wimp_RedrawWindow( &redrawblock, &more);
convert.x = redrawblock.rect.min.x - redrawblock.scroll.x;
convert.y = redrawblock.rect.max.y - redrawblock.scroll.y;
for (
;
more;
Wimp_GetRectangle( &redrawblock, &more)
)
{
workrect = redrawblock.cliprect;
Shell_ConvertRectToWorkarea( &workrect, convert);
Shell_WindRedraw2( &workrect, convert, info);
/* Most of the work is in this separate fn so that it can be called */
/* independantly within a fn which temporaraly redirects output to a */
/* sprite - see PlainRect.c */
}
return TRUE;
}
Shell_windblock *Shell_OpenWindow( void)
{
Shell_windblock *info;
if ( Shell_numwinds == Shell_MAXWINDS) Error_ReportFatal( 1, Error_PLACE "Too many GFX windows");
/* Should change the window storage to use a linked list (like each window's rect-list. */
Shell_numwinds++;
info = &Shell_windows[Shell_numwinds-1];
info->window = Window_CreateAndShow( "ShellWindow", /*maxtitlesize*/ 0, open_NEARLAST);
if ( info->window == 0)
Error_ReportFatal( 0, Error_PLACE "Shell_OpenGFXWindow -couldn't find 'ShellWindow' in templates");
/* This error-detection doesn't work - Window_CreateShow returns a non-zero window */
/* handle even if the templates don't have the window. This can cause problems! */
info->numrects = 0;
LinkList_Init( &info->anchor);
Event_Claim( event_REDRAW, info->window, event_ANY, Shell_WindRedraw, (void *) info);
return info;
}
Shell_rectblock *Shell_AddRectangle(
Shell_windblock *w,
const wimp_rect *rect,
Shell_redrawer redrawfn,
const void *reference
)
/* This creates a 'plain' rectangle in a window - it has no border, and the background colour */
/* will be the same as the background of the window. To give the rect a border and back/fore- */
/* colours, use Shell_MakeRectIcon. */
{
Shell_rectblock *r;
if ( (w-Shell_windows >= Shell_MAXWINDS) || (w-Shell_windows < 0))
Error_ReportFatal( 1, Error_PLACE "Invalid Shell_windblock in Shell_AddRectangle, '%p'", w);
w->numrects++;
r = Shell_SafeMalloc( sizeof( Shell_rectblock));
LinkList_AddToTail( &w->anchor, &r->header);
r->update_time = 0; /* minimum time between rect redraws */
r->last_update = 0;
r->rect = *rect; /* rectangle which encloses the rect's data */
r->icon.workarearect = *rect; /* border around the rect. */
r->redrawer = redrawfn;
r->saver = NULL; /* NULL or a valid rect saver */
r->ramsaver = NULL; /* NULL or a valid rect ramsaver */
r->size = 256; /* Default size. */
r->filetype = 0xfff; /* Default filetype is text. */
r->reference = (void *) reference;
r->window = w->window;
r->plot_icon = FALSE; /* This is a plain rect. */
Shell_CheckWindSizeAndRedraw( w->window, &r->rect);
/* This resizes the window if nesesary so that it contains the */
/* rectangle. Hence the window automatically expands to contain */
/* any rects added to it. */
return r;
}
Shell_rectblock *Shell_AddRectangle2(
Shell_windblock *w,
int xmin, int ymin, int xmax, int ymax,
Shell_redrawer redrawfn,
const void *reference
)
{
wimp_rect rect;
rect.min.x = xmin; rect.min.y = ymin;
rect.max.x = xmax; rect.max.y = ymax;
return Shell_AddRectangle( w, &rect, redrawfn, reference);
}
Shell_rectblock *Shell_AddRectangle3(
Shell_windblock *w,
int xmin, int ymin,
int xsize, int ysize,
Shell_redrawer redrawfn,
const void *reference
)
{
wimp_rect rect;
rect.min.x = xmin; rect.max.x = xmin + xsize;
rect.min.y = ymin; rect.max.y = ymin + ysize;
return Shell_AddRectangle( w, &rect, redrawfn, reference);
}
void Shell_ForceRectRedraw( Shell_rectblock *r)
{ window_redrawblock block;
r->last_update = clock();
block.window = r->window;
block.rect = r->rect;
Wimp_ForceRedraw( &block); /* The actual redraw will be done when the Wimp sends */
/* event_REDRAW on the next Shell/Event_Poll. */
return;
}
void Shell_ForceRectRedrawSlow( Shell_rectblock *r)
/* This only ForceRedraws a rectangle if the */
/* last redraw was a sufficiently long time ago */
{
clock_t t = clock();
if ( t - r->last_update >= r->update_time) {
r->last_update = t;
Shell_ForceRectRedraw( r);
}
return;
}
void Shell_ForceRectUpdate( Shell_rectblock *r)
/* This routine redraws a rectangle without clearing it */
/* to the background colour. Use for animation etc. */
/* The redraw loop occurs imediately, without polling */
/* the Wimp. */
{
window_redrawblock redrawblock;
Shell_convertpoint convert;
wimp_rect workrect;
BOOL more;
wimp_point rectsize;
rectsize.x = r->rect.max.x - r->rect.min.x;
rectsize.y = r->rect.max.y - r->rect.min.y;
redrawblock.window = r->window;
redrawblock.rect = r->rect;
Wimp_UpdateWindow( &redrawblock, &more);
convert.x = redrawblock.rect.min.x - redrawblock.scroll.x + r->rect.min.x;
convert.y = redrawblock.rect.max.y - redrawblock.scroll.y + r->rect.min.y;
for (
;
more;
Wimp_GetRectangle( &redrawblock, &more)
)
{
workrect.max.x = redrawblock.cliprect.max.x - convert.x;
workrect.min.x = redrawblock.cliprect.min.x - convert.x;
workrect.max.y = redrawblock.cliprect.max.y - convert.y;
workrect.min.y = redrawblock.cliprect.min.y - convert.y;
( *(r->redrawer) ) ( convert, rectsize, r->reference, &workrect);
/* Call the redrawing function for the rectangle */
}
}
void Shell_ForceRectUpdateSlow( Shell_rectblock *r)
/* This only ForceUpdates a rectangle if the */
/* last redraw was a sufficiently long time ago */
{
clock_t t = clock();
if ( t - r->last_update >= r->update_time) {
r->last_update = t;
Shell_ForceRectUpdate( r);
}
return;
}
void Shell_SetWindowTitle( window_handle window, char *text)
/* There used to be code here, but DeskLib 2.04 has a function built in which actually */
/* works properly! */
{
Window_SetTitle( window, text);
}